package com.engine.jucailinkq.attendance.attendanceanalysis.job;


import com.engine.jucailinkq.attendance.attendanceanalysis.service.UtilService;
import com.engine.jucailinkq.attendance.attendanceanalysis.service.impl.UtilServiceImpl;
import com.engine.jucailinkq.attendance.attendanceanalysis.wrapper.AttendanceAnalysisWrapper;
import com.engine.jucailinkq.attendance.attendanceplan.service.AttendancePlanService;
import com.engine.jucailinkq.attendance.attendanceplan.service.impl.AttendancePlanServiceImpl;
import com.engine.jucailinkq.attendance.workflow.service.AllowanceService;
import com.engine.jucailinkq.attendance.workflow.service.impl.AllowanceServiceImpl;
import com.engine.common.util.*;
import com.engine.jucailinkq.common.util.CommonUtil;
import com.engine.jucailinkq.common.util.DateUtil;
import com.engine.jucailinkq.common.util.DbTools;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import weaver.conn.RecordSet;
import weaver.general.BaseBean;
import weaver.general.Util;
import weaver.interfaces.schedule.BaseCronJob;

import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

@Slf4j
public class AttendanceAnalysisJob extends BaseCronJob {
    private AttendancePlanService basicsetService = ServiceUtil.getService(AttendancePlanServiceImpl.class);

    private AttendanceAnalysisWrapper attendanceAnalysisService = ServiceUtil.getService(AttendanceAnalysisWrapper.class);

    private AllowanceService allowanceService = ServiceUtil.getService(AllowanceServiceImpl.class);

    private UtilService utilService = ServiceUtil.getService(UtilServiceImpl.class);

    private String executeDate;
    @Override
    public void execute() {
        log.info("********AttendanceAnalysisJob  start********");

        String useDate = com.time.util.DateUtil.getCurrentTime("yyyy-MM-dd");
//        if (executeDate != null && !"".equals(executeDate)){
//            useDate = executeDate;
//        }
        log.info("********AttendanceAnalysisJob  executeDate :[{}]********",useDate);

        RecordSet rs = new RecordSet();
        String queryDepartEmployeeSql = "select resourceid ,changedate  from HRMSTATUSHISTORY  where type_n = 5 and changedate='"+DateUtil.beforeDay(useDate,1)+"'";
        List<String> departEmployeeList = Lists.newArrayList(DbTools.getSqlToList(queryDepartEmployeeSql).stream().map(e->e.get("resourceid").toString()).collect(Collectors.toSet()));
        List<List<String>> departEmployeePartition = Lists.partition(departEmployeeList,200);

        String queryDepartEmployeeSqlA = "select resourceid id,changedate name from HRMSTATUSHISTORY  where type_n = 5";
        //获取离职日期
        Map<String,Object> departEmployeeMap = DbTools.getSqlToMapList(queryDepartEmployeeSqlA);

        String queryUserSql = "select id,departmentid,subcompanyid1,companystartdate from hrmresource where status <> '5' and status <> '4' and status <> '7'";
        List<Map<String,Object>> userList = DbTools.getSqlToList(queryUserSql);
        for (List<String> userIdPartition :departEmployeePartition){
            String sql = "select id,departmentid,subcompanyid1,companystartdate from hrmresource where id ("+String.join(",",userIdPartition)+")";
            userList.addAll(DbTools.getSqlToList(sql));
        }


        Map<String, Object> getAttendanceparam = Maps.newHashMap();
        getAttendanceparam.put("userList",userList);
        getAttendanceparam.put("executeDate",useDate);

        Map<String, Object> attendanceCycle = utilService.getAttendanceCycle(getAttendanceparam);
        Set<String> allDates = Sets.newHashSet();
        for (Map.Entry<String, Object> entry : attendanceCycle.entrySet()){
            Set<String> sets = (Set<String>)entry.getValue();
            for (String date :sets){
                if (DateUtil.getTime(date).compareTo(DateUtil.getTime(DateUtil.beforeDay(useDate,1))) != 0){
                    allDates.add(date);
                    allDates.add(DateUtil.beforeDay(date,1));
                    allDates.add(DateUtil.AfterDay(date,1));
                }
            }
        }

        allDates.add(useDate);
        List<String> allDateList = Lists.newArrayList(allDates);
        allDateList = allDateList.stream().sorted(Comparator.comparing(e -> DateUtil.getTime(e).toInstant(ZoneOffset.of("+8")).toEpochMilli())).collect(Collectors.toList());
        allDateList = allDateList.stream().map(e->"'"+e+"'").collect(Collectors.toList());
        BaseBean baseBean = new BaseBean();
        baseBean.writeLog("AttendanceAnalysisJob allDateList:" + allDateList);

        List<List<String>> needAnalysisDateList = Lists.partition(allDateList,200);
        List<Map<String,Object>> dataList = Lists.newArrayList();
        List<Map<String,Object>> attendaceResult = Lists.newArrayList();
        for (List<String> list:needAnalysisDateList){
            String dateStrs = String.join(",",list);
            String sql = "select id,userid,signdate,signtime from hrmschedulesign where isincom=1 and signdate in ("+dateStrs+") order by signdate,signtime";
            List<Map<String,Object>> hrmschedulesignList = DbTools.getSqlToList(sql);
            if (hrmschedulesignList.size() > 0){
                dataList.addAll(hrmschedulesignList);
            }

            //补打卡记录
            sql = "select id,bdkry userid,dkrq signdate,dksj signtime from uf_jcl_kq_bdkjl where dkrq in ("+dateStrs+") and jlzt=1 order by dkrq,dksj";
            List<Map<String,Object>> makeUpList = DbTools.getSqlToList(sql);
            if (makeUpList.size() > 0){
                dataList.addAll(makeUpList);
            }

            sql = "select sjzt,sgsj,ygid,rq from uf_jcl_kq_cqjg where rq in ("+dateStrs+")";
            List<Map<String,Object>> resultList = DbTools.getSqlToList(sql);
            if (resultList.size() > 0){
                attendaceResult.addAll(resultList);
            }
        }


        dataList = dataList.stream().sorted(Comparator.comparing(e->DateUtil.getTime(e.get("signdate")+" "+e.get("signtime")).toInstant(ZoneOffset.of("+8")).toEpochMilli())).collect(Collectors.toList());
        Map<String, List<Map<String,Object>>> collect = dataList.stream().collect(Collectors.groupingBy(e -> Util.null2String(e.get("userid"))));

        Map<String,List<Map<String,Object>>> attendaceGroupById = attendaceResult.stream().collect(Collectors.groupingBy(e->e.get("ygid").toString()));

        //初始化扩展类
        CommonUtil.initExtensionClassHolder();

        for (Map<String,Object> userMap:userList) {

            String userId = Util.null2String(userMap.get("id"));
            //入职日期
            String companystartDate = Util.null2String(userMap.get("companystartdate"));

            //离职日期
            String terminationDate = Util.null2String(departEmployeeMap.get(userId));

            List<String> analysisDateListOld = Lists.newArrayList((Set<String>) attendanceCycle.get(userId));
            if (CollectionUtils.isEmpty(analysisDateListOld)) {
                continue;
            }
            List<String> analysisDateList = new ArrayList<>();
            for (String date : analysisDateListOld) {
                if (("".equals(companystartDate) || DateUtil.getTime(date).compareTo(DateUtil.getTime(companystartDate)) > 0)
                        && ("".equals(terminationDate) || DateUtil.getTime(date).compareTo(DateUtil.getTime(terminationDate)) < 0)) {
                    analysisDateList.add(date);
                }

                // 入职日期及之前、离职日期及之后的数据逻辑删除
                if ((StringUtils.isNotEmpty(companystartDate) && DateUtil.getTime(date).compareTo(DateUtil.getTime(companystartDate)) <= 0)
                        || (StringUtils.isNotEmpty(terminationDate) && DateUtil.getTime(date).compareTo(DateUtil.getTime(terminationDate)) >= 0)) {
                    rs.executeUpdate("UPDATE uf_jcl_kq_cqjg SET sfsc = 1 WHERE ygid = ? AND rq = ?", userId, date);
                }
            }
            if (CollectionUtils.isEmpty(analysisDateList)) {
                continue;
            }

            try {
                analysisDateList = analysisDateList.stream().filter(e -> "".equals(companystartDate) || DateUtil.getTime(e).compareTo(DateUtil.getTime(companystartDate)) >= 0).sorted(Comparator.comparing(e -> DateUtil.getTime(e).toInstant(ZoneOffset.of("+8")).toEpochMilli())).collect(Collectors.toList());
                //日期对应的打卡数据
                Map<String, Map<String, Object>> clockInTimeMap = Maps.newHashMap();
                List<String> finalAnalysisDateList = analysisDateList;
                /**获得人员考勤项目*/
                Map<String, Object> paramMap = Maps.newHashMap();
                paramMap.put("startDate", DateUtil.beforeDay(useDate, 1));
                paramMap.put("endDate", DateUtil.beforeDay(useDate, 1));
                paramMap.put("resourceId", userId);
                Map<String, Object> dataMap = basicsetService.getAttendanceItemsByPerson(paramMap);
                List<Map<String, Object>> attendanceItems = (List<Map<String, Object>>) dataMap.get("data");
                /**
                 *获得人员综合工时
                 */
                Map<String, Object> workHourdataMap = basicsetService.getWorkHoursItemByPerson(paramMap);
                List<Map<String, Object>> workHourItems = (List<Map<String, Object>>) workHourdataMap.get("data");

                Map<String, List<Map<String, Object>>> attendaceResultMap = Maps.newHashMap();
                List<Map<String, Object>> attendaceResultByUser = attendaceGroupById.get(userId);
                if (attendaceResultByUser != null && attendaceResultByUser.size() > 0) {
                    attendaceResultMap = attendaceResultByUser.stream().collect(Collectors.groupingBy(e -> e.get("rq").toString()));
                }
                Map<String, List<Map<String, Object>>> finalAttendaceResultMap = attendaceResultMap;
                attendanceAnalysisService.attendanceAnalysis(userId, finalAnalysisDateList, collect.get(userMap.get("id")), attendanceItems, workHourItems, clockInTimeMap, finalAttendaceResultMap);
            } catch (Exception e) {
                log.error("AttendanceAnalysisJob userId:[{}],analysisDateList: [{}]", userId, analysisDateList);
                log.error("AttendanceAnalysisJob error : [{}]", e);
            }
        }
        Map<String,Object> param = Maps.newHashMap();
        param.put("startDate",DateUtil.beforeDay(useDate,3));
        param.put("endDate",useDate);
        allowanceService.addAllowanceRecords(param);
        log.info("********AttendanceAnalysisJob  end********");
    }

}
